package com.mbuswidget;

import java.io.IOException;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.TimerTask;

import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.text.SpannableString;
import android.text.style.UnderlineSpan;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

public class MBusWidgetService extends Service {
	private static final int START_STICKY = 0;
	private NotificationManager mNM;

	private MBusInfo mbusInfo;

	// Unique Identification Number for the Notification.
	// We use it on Notification start, and to cancel it.
	private int NOTIFICATION = R.string.local_service_started;

	private ArrayList<Integer> appWidgetIds;

	private SharedPreferences prefs;

	private LocationManager locManager;
	private MBusWidgetServicePowerListener powerListener;
	private boolean isUserChangingPage = false;
	private long timeOfDownload = 0;
	private int downloadInterval;
	private boolean isAutoDownloadEnabled = false;
	private boolean isAnnouceShutdown = false;
	private HandshakeCompletedListener listener = new HandshakeCompletedListener() {
		
		public void handshakeCompleted(HandshakeCompletedEvent event) {
			// TODO Auto-generated method stub
			Log.w("TLSIcon", "SSL Connection Established " + event.toString());
		}
	};

	// Number of times to try and redownload data.
	private int DownloadRetryCount = 3;

	/**
	 * Class for clients to access. Because we know this service always runs in
	 * the same process as its clients, we don't need to deal with IPC.
	 */
	public class LocalBinder extends Binder {
		MBusWidgetService getService() {
			return MBusWidgetService.this;
		}
	}

	public MBusInfo getBusInfo() {
		if (mbusInfo != null) {
			return new MBusInfo(mbusInfo);
		}
		return null;
	}

	@Override
	public void onCreate() {
		Toast.makeText(this, "MBusWidget Service Started", Toast.LENGTH_SHORT);

		// prefs = this.getApplicationContext().getSharedPreferences(
		// MBusWidgetConstants.PREFS_NAME, 0);
		prefs = PreferenceManager.getDefaultSharedPreferences(this);

		// requestLocationUpdates(provider, time interval (ms), dist change (m),
		// listener)
		locManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		startLocationListener();

		appWidgetIds = MBusWidgetConstants.GetWidgetIDs(prefs);
		String temp = new String();
		for (Integer i : appWidgetIds) {
			temp += i + ",";
		}

		// Log.w("mbuswidget", "Service widgets: " + temp);

		powerListener = new MBusWidgetServicePowerListener();

		IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
		filter.addAction(Intent.ACTION_SCREEN_OFF);
		registerReceiver(powerListener, filter);

		downloadInterval = MBusWidgetConstants.GetDownloadInterval(prefs);
		isAutoDownloadEnabled = MBusWidgetConstants
				.GetDownloadIntervalEnabled(prefs);

		// Log.w("mbuswidget", "Service: Auto "
		// + (isAutoDownloadEnabled ? " on" : "off") + " Interval: "
		// + downloadInterval);

		// Service started lets get the information
		// TODO: Handle failing to get data...
		// loadData();

		// Retrieve the data using runnable
		updateTimeHandler.post(mDownloadTask);
		startLocationListener();

		// Display a notification about us starting. We put an icon in the
		// status bar.
		// showNotification();

		// updateWidgets();

	}

	// Update the timer on
	private Handler updateTimeHandler = new Handler();
	private Runnable mUpdateTimeTask = new Runnable() {

		public void run() {
			// TODO Auto-generated method stub
			long millis = System.currentTimeMillis() - timeOfDownload;
			int seconds = (int) (millis / 1000);

			// Log.w("mbuswidget", "Service: Update Time Task " + seconds);

			updateWidgetsTimeElasped(MBusWidgetConstants.DATA_LAST_RECIEVED_PREX
					+ formatTimeToString(seconds)
					+ MBusWidgetConstants.DATA_LAST_RECIEVED_SUFX);

			int index = 0;
			for (int cutoff : MBusWidgetConstants.UpdateTaskCutoffs) {
				// As long as seconds is less than the cut off at the certain
				// step
				// restart the task with the interval
				if (seconds < cutoff) {
					updateTimeHandler
							.postDelayed(
									this,
									MBusWidgetConstants.UpdateTaskInterval[index] * 1000);
					return;
				}
				index++;
			}

			updateWidgetsTimeElasped(MBusWidgetConstants.DATA_IS_OLD);
		}
	};

	private Runnable mDownloadTask = new Runnable() {

		public void run() {
			// TODO Auto-generated method stub
			loadData();
			if (isAutoDownloadEnabled) {
				updateTimeHandler.postDelayed(this, downloadInterval * 1000);
			}
		}
	};

	// Lets try download the data DownloadRetryCount times.
	public boolean DownloadMBusInfo() {
		int count = 0;
		mbusInfo = null;
		updateWidgetsTimeElasped(MBusWidgetConstants.DOWNLOADING_NEW_DATA);
		while (count < DownloadRetryCount) {
			try {
				Document mBusInfoDoc = GetMBusDocViaHTTP();
				if (mBusInfoDoc != null) {
					mbusInfo = new MBusInfo(mBusInfoDoc,
							getApplicationContext());
					timeOfDownload = System.currentTimeMillis();
					return true;
				}
			} catch (Exception e) {
				// Log.e("mbuswidget", e.toString());
			}
			count++;
		}
		return false;
	}

	public void updateWidgetsTimeElasped(String text) {
		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
				.getApplicationContext());
		if (appWidgetIds != null && appWidgetIds.size() > 0) {
			for (int widgetId : appWidgetIds) {
				RemoteViews remoteViews;
				ArrayList<String> stopStringList = MBusWidgetConstants
						.GetWidgetStopList(prefs, widgetId);
				if (stopStringList.size() != 0) {
					remoteViews = new RemoteViews(getPackageName(),
							R.layout.mbuswidget);
					remoteViews.setTextViewText(R.id.dataLastUpdated, text);
					// Log.w("mbuswidget", "Service: Updating widget " +
					// widgetId
					// + " to " + text);
					appWidgetManager.updateAppWidget(widgetId, remoteViews);
				}
			}
		}
	}

	public void updateWidgets() {
		// Will will handle this function. This is what actually updates the
		// widgets on the display
		// Log.w("mbuswidget", "SERVICE: Update Widgets Called");

		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
				.getApplicationContext());

		if (appWidgetIds != null && appWidgetIds.size() > 0) {
			for (int widgetId : appWidgetIds) {

				RemoteViews remoteViews;

				// Log.w("mbuswidget", "Looking at widgetId: " + widgetId);
				// Log.w("mbuswidget",
				// "There are currently " + appWidgetIds.size()
				// + " widgets");

				ArrayList<String> stopStringList = MBusWidgetConstants
						.GetWidgetStopList(prefs, widgetId);
				ArrayList<String> blacklistedRouteList = MBusWidgetConstants
						.GetWidgetBlacklist(prefs, widgetId);

				// Check if widget has been configured yet.
				if (stopStringList.size() != 0) {
					// Log.w("mbuswidget", "Service: Widget " + widgetId +
					// " has " + stopStringList.size() + " stops");
					// The widget has stops configured. Lets assume it has been
					// setup

					// Show the working layout.
					remoteViews = new RemoteViews(getPackageName(),
							R.layout.mbuswidget);

					// TODO: Add Shared Preference for currently selected index
					// Should be set to which stop is currently selected in the
					// widget
					int stopListIndex = MBusWidgetConstants.GetStopIndex(prefs,
							widgetId);

					if (stopListIndex < 0) {
						stopListIndex = stopStringList.size() + stopListIndex;
					} else if (stopListIndex >= stopStringList.size()) {
						stopListIndex = stopListIndex % stopStringList.size();
					}

					if (!isUserChangingPage
							&& MBusWidgetConstants.GetUseLocation(prefs,
									widgetId) && mbusInfo != null) {
						int tempIndex = findClosestStopToCurrentLocation(stopStringList);
						if (tempIndex >= 0)
							stopListIndex = tempIndex;
					}

					MBusWidgetConstants.SetStopIndex(prefs, widgetId,
							stopListIndex);

					String widgetBodyTxt = new String();

					String stopName = stopStringList.get(stopListIndex);
					if (mbusInfo != null) {

						ArrayList<Pair<BusRoute, BusStop>> stopInfo = mbusInfo
								.getRouteAndStopInfoForStopWithName(stopName);

						int MaxArrivalTimes = MBusWidgetConstants
								.GetMaxArrivalTimes(prefs, widgetId);

						for (Pair<BusRoute, BusStop> pair : stopInfo) {
							BusRoute route = pair.getFirst();
							BusStop stop = pair.getSecond();

							// Check if route is blacklisted, if so don't
							// include it
							// in
							// the widget
							if (Collections.binarySearch(blacklistedRouteList,
									route.getName()) >= 0) {
								continue;
							}

							String routeInfo = new String();
							routeInfo += route.getShortName() + ": ";

							String times = null;
							for (int i = 0; i < stop.getArrivalTimes().size()
									&& i < MaxArrivalTimes; i++) {
								Double time = stop.getArrivalTimes().get(i);
								String temp = formatTimeToString(time);
								if (times == null && temp.length() != 0) {
									times = temp;
								} else {
									if (temp != null && temp.length() != 0) {
										times += ", " + temp;
									}
								}
							}

							if (times != null) {
								if (widgetBodyTxt.length() != 0)
									widgetBodyTxt += "\n";
								widgetBodyTxt += routeInfo + times;
							}
						}

						if (widgetBodyTxt.length() == 0) {
							widgetBodyTxt = MBusWidgetConstants.STOP_NOT_SERVICED;
						}
					} else {
						if (isAutoDownloadEnabled) {
							widgetBodyTxt = MBusWidgetConstants.REFRESHING_WIDGET;
						} else {
							widgetBodyTxt = MBusWidgetConstants.PRESS_RELOAD;
						}
					}

					if (stopStringList.size() > 1) {
						remoteViews.setBoolean(R.id.nextStopBtn, "setEnabled",
								true);
						Intent showNextStop = new Intent(this,
								MBusWidgetService.class);
						showNextStop.putExtra(
								MBusWidgetConstants.SHOW_NEXT_STOP, true);
						showNextStop.putExtra(
								AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
						showNextStop.setAction(MBusWidgetConstants.PREFS_NAME
								+ System.currentTimeMillis());
						PendingIntent pendingShowNextStop = PendingIntent
								.getService(getApplicationContext(), 0,
										showNextStop,
										PendingIntent.FLAG_UPDATE_CURRENT);
						remoteViews.setOnClickPendingIntent(R.id.nextStopBtn,
								pendingShowNextStop);

						remoteViews.setBoolean(R.id.previousStopBtn,
								"setEnabled", true);
						Intent showPrevStop = new Intent(this,
								MBusWidgetService.class);
						showPrevStop.putExtra(
								AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
						showPrevStop.putExtra(
								MBusWidgetConstants.SHOW_PREV_STOP, true);
						showPrevStop.setAction(MBusWidgetConstants.PREFS_NAME
								+ System.currentTimeMillis());
						PendingIntent pendingShowPrevStop = PendingIntent
								.getService(getApplicationContext(), 0,
										showPrevStop,
										PendingIntent.FLAG_UPDATE_CURRENT);
						remoteViews.setOnClickPendingIntent(
								R.id.previousStopBtn, pendingShowPrevStop);

					} else {
						remoteViews.setBoolean(R.id.nextStopBtn, "setEnabled",
								false);
						remoteViews.setBoolean(R.id.previousStopBtn,
								"setEnabled", false);
					}

					// Log.w("mbuswidget", widgetBodyTxt);

					if (isAutoDownloadEnabled) {
						remoteViews.setTextViewText(R.id.dataLastUpdated,
								MBusWidgetConstants.REFRESHING_WIDGET);
					} else {
						remoteViews.setTextViewText(R.id.dataLastUpdated,
								MBusWidgetConstants.PRESS_RELOAD);
					}

					remoteViews.setTextColor(R.id.widgetText, Color.BLACK);
					remoteViews.setTextViewText(R.id.widgetText, widgetBodyTxt);

					remoteViews.setTextColor(R.id.stopLabel, Color.BLACK);
					SpannableString content = new SpannableString(stopName);
					content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
					remoteViews.setTextViewText(R.id.stopLabel, content);

					// TODO: This must activiate a force reload in the
					// service...
					Intent startServiceIntent = new Intent(this,
							MBusWidgetService.class);
					startServiceIntent.putExtra(
							MBusWidgetConstants.FORCE_SERVICE_RELOAD, true);
					startServiceIntent.setAction(MBusWidgetConstants.PREFS_NAME
							+ System.currentTimeMillis());

					// To react to a click we have to use a pending intent as
					// the
					// onClickListener is
					// excecuted by the homescreen application
					PendingIntent pendingIntent = PendingIntent.getService(
							getApplicationContext(), 0, startServiceIntent,
							PendingIntent.FLAG_UPDATE_CURRENT);

					remoteViews.setOnClickPendingIntent(R.id.reloadBtn,
							pendingIntent);

				} else {
					// Log.w("mbuswidget",
					// "Service: Setting widget to initalize view");
					remoteViews = new RemoteViews(getPackageName(),
							R.layout.mbuswidgetinitialized);
				}

				// Make entire widget clickable

				Intent openConfigIntent = new Intent(getApplicationContext(),
						MBusWidgetConfiguration.class);
				openConfigIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
						widgetId);
				openConfigIntent.setAction(MBusWidgetConstants.PREFS_NAME
						+ System.currentTimeMillis());
				PendingIntent pendingOpenConfig = PendingIntent.getActivity(
						getApplicationContext(), 0, openConfigIntent, 0);
				remoteViews.setOnClickPendingIntent(
						R.id.mbusWidgetRelativeLayout, pendingOpenConfig);

				appWidgetManager.updateAppWidget(widgetId, remoteViews);

				// Log.w("mbuswidget", "Service Update Widget " + widgetId
				// + " End Loop");
			}
			// stopSelf();

		}
		isUserChangingPage = false;
	}

	public int onStartCommand(Intent intent, int flags, int startId) {
		// Log.i("mbuswidget", "Serviced Started, Received start id " + startId
		// + ": " + intent);

		if (intent.getBooleanExtra(MBusWidgetConstants.FORCE_RESTART, false)) {
			isAnnouceShutdown = true;
			stopSelf();
		}

		if (intent.getBooleanExtra(MBusWidgetConstants.SERVICE_ANNOUNCE, false)) {
			Toast.makeText(this, R.string.local_service_started,
					Toast.LENGTH_SHORT).show();
		}

		int widgetID = intent.getIntExtra(MBusWidgetConstants.WIDGET_CREATED,
				AppWidgetManager.INVALID_APPWIDGET_ID);
		if (widgetID != AppWidgetManager.INVALID_APPWIDGET_ID) {

			int index = (-Collections.binarySearch(appWidgetIds, widgetID) - 1);
			if (index >= 0) {
				appWidgetIds.add(index, widgetID);

				// Log.w("mbuswidget", "Widget was added to screen with id: "
				// + widgetID + " index: " + index);
				MBusWidgetConstants.SetWidgetIDs(prefs, appWidgetIds);

				updateTimeHandler.removeCallbacks(mUpdateTimeTask);
				if (DownloadMBusInfo()) {
					// TODO: Show failed to download data...
					updateTimeHandler.post(mUpdateTimeTask);
				} else {
					updateWidgetsTimeElasped(MBusWidgetConstants.DATA_ERROR);
				}
			}
		}

		int[] deletedWidgets = intent
				.getIntArrayExtra(MBusWidgetConstants.WIDGETS_DELETED);
		if (deletedWidgets != null) {
			for (int i : deletedWidgets) {
				int index = Collections.binarySearch(appWidgetIds, i);
				if (index >= 0) {

					int removed = appWidgetIds.remove(index);
					// Log.w("mbuswidget",
					// "Widget was deleted from screen with id: "
					// + removed + ",index:" + index);
				}
			}
			// Check if no more widgets exist on the screen and kill the
			// service
			if (appWidgetIds.isEmpty()) {
				stopSelf();
			}
		}

		// Force Data to reload
		if (intent.getBooleanExtra(MBusWidgetConstants.FORCE_SERVICE_RELOAD,
				false)) {
			loadData();
		}

		if (intent.getBooleanExtra(MBusWidgetConstants.SHOW_NEXT_STOP, false)) {
			int widgetId = intent.getIntExtra(
					AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
			if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
				int index = MBusWidgetConstants.GetStopIndex(prefs, widgetId);
				MBusWidgetConstants.SetStopIndex(prefs, widgetId, index + 1);
				isUserChangingPage = true;
			}
		}

		if (intent.getBooleanExtra(MBusWidgetConstants.SHOW_PREV_STOP, false)) {
			int widgetId = intent.getIntExtra(
					AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
			if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
				int index = MBusWidgetConstants.GetStopIndex(prefs, widgetId);
				MBusWidgetConstants.SetStopIndex(prefs, widgetId, index - 1);
				isUserChangingPage = true;
			}
		}

		// Screen was turned off
		if (intent.getBooleanExtra(MBusWidgetConstants.SCREEN_STATE_OFF, false)) {
			// Log.w("mbuswidget", "Service: Screen turned off");
			updateTimeHandler.removeCallbacks(mUpdateTimeTask);
			updateTimeHandler.removeCallbacks(mDownloadTask);
			locManager.removeUpdates(locListener);

			// TODO: Add clearing for timer that calls update on data service.
		}

		// Screen was turned on
		if (intent.getBooleanExtra(MBusWidgetConstants.SCREEN_STATE_ON, false)) {
			// Log.w("mbuswidget", "Service: Screen turned on");
			if (isAutoDownloadEnabled) {
				loadData();
			}

			startLocationListener();
			if (isAutoDownloadEnabled) {
				updateTimeHandler.postDelayed(mDownloadTask,
						downloadInterval * 1000);
			}
		}

		updateWidgets();

		super.onStart(intent, startId);

		return START_STICKY;
	}

	// @Override
	// public void onStart(Intent intent, int startId) {
	//
	// }

	public String formatTimeToString(Double time) {
		String string = new String();
		Integer minutes = (int) (time / 60.0);
		Integer seconds = (int) (time % 60.0);
		if (minutes != 0) {
			string += minutes + "m";
		}
		if (seconds != 0) {
			string += seconds + "s";
		}
		return string;
	}

	public String formatTimeToString(int time) {
		String string = new String();
		Integer minutes = (int) (time / 60);
		Integer seconds = (int) (time % 60);
		if (minutes != 0) {
			string += minutes + "m";
		}
		if (seconds != 0 || (seconds == 0 && minutes == 0)) {
			string += seconds + "s";
		}
		return string;
	}

	@Override
	public void onDestroy() {
		// Cancel the persistent notification.

		// Tell the user we stopped.
		if (isAnnouceShutdown) {
			Toast.makeText(this, R.string.local_service_stopped,
					Toast.LENGTH_SHORT).show();
		}
		updateTimeHandler.removeCallbacks(mUpdateTimeTask);
		updateTimeHandler.removeCallbacks(mDownloadTask);
		locManager.removeUpdates(locListener);
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	public void loadData() {
		updateTimeHandler.removeCallbacks(mUpdateTimeTask);
		if (DownloadMBusInfo()) {
			// TODO: Show failed to download data...
			updateWidgets();
			updateTimeHandler.post(mUpdateTimeTask);
		} else {
			updateWidgetsTimeElasped(MBusWidgetConstants.DATA_ERROR);
		}
	}

	// This is the object that receives interactions from clients. See
	// RemoteService for a more complete example.
	private final IBinder mBinder = new LocalBinder();

	/**
	 * Show a notification while this service is running.
	 */
	private void showNotification() {
		// In this sample, we'll use the same text for the ticker and the
		// expanded notification
		CharSequence text = "MBUS STARTED";

		// Set the icon, scrolling text and timestamp
		Notification notification = new Notification(R.drawable.icon, text,
				System.currentTimeMillis());

		// The PendingIntent to launch our activity if the user selects this
		// notification
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, MBusWidgetService.class), 0);

		// Set the info for the views that show in the notification panel.
		notification.setLatestEventInfo(this, "something", text, contentIntent);

		// Send the notification.
		mNM.notify(NOTIFICATION, notification);
	}

	public Document GetMBusDocViaHTTP() {
		Document doc = null;
		try {
			URL url = new URL(MBusWidgetConstants.MBUSLINK);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Accept", "application/xml");

			/* Get a SAXParser from the SAXPArserFactory. */
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();

			sp.getXMLReader();

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			doc = db.parse(new InputSource(url.openStream()));
		} catch (Exception e) {
			// Log.e("", e.toString());
		}

		return doc;
	}

	public Document XMLfromString(String xml) {

		Document doc = null;

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
			is.setCharacterStream(new StringReader(xml));
			doc = db.parse(is);

		} catch (ParserConfigurationException e) {
			System.out.println("XML parse error: " + e.getMessage());
			return null;
		} catch (SAXException e) {
			System.out.println("Wrong XML file structure: " + e.getMessage());
			return null;
		} catch (IOException e) {
			System.out.println("I/O exeption: " + e.getMessage());
			return null;
		}

		return doc;
	}

	public int findClosestStopToCurrentLocation(ArrayList<String> stops) {
		// Log.w("mbuswidget", "Service: Waiting for Location");
		Location myLoc = loc;
		if (myLoc == null) {
			// Log.w("mbuswidget", "Service: No Location!");
			return -1;
		}
		// Log.w("mbuswidget", "Service: Got Location!");
		double minDistance = 1e99;
		int minIndex = -1;
		for (int x = 0; x < stops.size(); x++) {
			ArrayList<Pair<BusRoute, BusStop>> stopInfo = mbusInfo
					.getRouteAndStopInfoForStopWithName(stops.get(x));
			if (stopInfo.size() == 0) {
				// Handle the cause where no buses handle that stop
				// Log.w("mbuswidget",
				// "Service: Error could not find any stops with name: "
				// + stops.get(x));
				return -1;
			} else {
				BusStop stop = stopInfo.get(0).getSecond();
				Double distance = new Double(myLoc.distanceTo(stop
						.getLocation()));
				// Log.w("mbuswidget", "Service: " + stop.getShortName()
				// + ", dist: " + distance);
				if (distance < minDistance) {
					minDistance = distance;
					minIndex = x;
				}
			}
		}
		return minIndex;
	}

	private Location loc;
	private LocationListener locListener = new LocationListener() {

		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub
			if (status == LocationProvider.AVAILABLE) {
				// Log.v("mbuswidget", "Status Changed: Available");
			} else if (status == LocationProvider.TEMPORARILY_UNAVAILABLE) {
				// Log.v("mbuswidget", "Status Changed: Temp. Unavailable");
			} else if (status == LocationProvider.OUT_OF_SERVICE) {
				// Log.v("mbuswidget", "Status Changed: Out of Service");
				loc = null;
			}
		}

		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub

		}

		public void onProviderDisabled(String provider) {
			// TODO Auto-generated method stub

		}

		public void onLocationChanged(Location location) {
			// TODO Auto-generated method stub
			loc = new Location(location);
			updateWidgets();
		}
	};

	private void startLocationListener() {
		if (MBusWidgetConstants.GetGPSLocationEnabled(prefs)) {
			locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
					MBusWidgetConstants.GPS_TIME_INTERVAL,
					MBusWidgetConstants.GPS_DIST_INTERVAL, locListener);
		}
		if (MBusWidgetConstants.GetNetworkLocationEnabled(prefs)) {
			locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
					MBusWidgetConstants.GPS_TIME_INTERVAL,
					MBusWidgetConstants.GPS_DIST_INTERVAL, locListener);
		}
	}

}
